package com.vecspace.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import com.vecspace.utils.log.HLogger;

/**
 * 文件工具类
 */
public class FileUtil {
    private FileUtil() {}

    /**
     * 列出所有当前层的文件和目录
     * 
     * @param dir            目录名称
     * @return fileList    列出的文件和目录
     */
    public static File[] ls(String dir) {
        return new File(dir).listFiles();
    }
    
    /**
     * 根据需要创建文件夹
     * 
     * @param dirPath 文件夹路径
     * @param del    存在文件夹是否删除
     */
    public static void mkdir(String dirPath,boolean del) {
        File dir = new File(dirPath);
        if(dir.exists()) {
            if(del) {
                dir.delete();
            }
            else {
            	return;
            }
        }
        dir.mkdirs();
    }
    
    /**
     * 删除单个文件
     * @param fileName  被删除文件的文件名 
     * @return 单个文件删除成功返回true,否则返回false
     */
    public static boolean deleteFile(String fileName){
    	File file = new File(fileName);
    	if(file.exists() && file.isFile()){
    		file.delete();
    		return true;
    	}
    	else{
    		return false;
    	}
    }
    
    /**
     * 删除文件和目录
     * 
     * @param path
     * @throws Exception
     */
    public static void rm(String path) throws Exception{
        HLogger.DEFAULT().debug("需要删除的文件: " + path);
        File file = new File(path);
        if(!file.exists()) {            
            	HLogger.DEFAULT().warn("文件<" + path + ">不存在");
            return;
        }
        if(file.isDirectory()) {
            File[] fileList = file.listFiles();
            if(fileList == null || fileList.length == 0) {
                file.delete();
            } else {
                for (File _file : fileList) {
                    rm(_file.getAbsolutePath());
                }
            }
        file.delete();
        } else {
            file.delete();
        }
    }
    
    /**
     * 移动文件
     * 
     * @param source     源文件
     * @param target         目标文件
     * @param cache        文件缓存大小
     * @throws Exception
     */
    public static void move(String source,String target,int cache) throws Exception {
        if(source.trim().equals(target.trim())) {
            return;
        }
        byte[] buffer = new byte[cache];
        FileInputStream fromFile = new FileInputStream(source);
        FileOutputStream toFile = new FileOutputStream(target);
        int readLen = fromFile.read(buffer);
        while(readLen > 0) {
            toFile.write(buffer,0,readLen);
            readLen = fromFile.read(buffer);
        }
        toFile.flush();
        toFile.close();
        fromFile.close();
        new File(source).deleteOnExit();
    }
    
    /**
     * 把属性文件转换成Map
     * 
     * @param propertiesFile
     * @return
     * @throws Exception
     */
    public static final Map<String, String> getPropertiesMap(String propertiesFile) throws Exception{
        Properties properties = new Properties();
        FileInputStream inputStream = new FileInputStream(propertiesFile);
        properties.load(inputStream);
        Map<String, String> map = new HashMap<String, String>();
        Set<Object> keySet = properties.keySet();
        for (Object key : keySet) {
            map.put((String)key, properties.getProperty((String)key));
        }
        return map;
    }
    
    public static final Map<String, String> getPropertiesMap(Class<?> clazz,String fileName) throws Exception{
        Properties properties = new Properties();
        InputStream inputStream = clazz.getResourceAsStream(fileName);
        if(inputStream == null) {
            inputStream = clazz.getClassLoader().getResourceAsStream(fileName);
        }
        properties.load(inputStream);
        Map<String, String> map = new HashMap<String, String>();
        Set<Object> keySet = properties.keySet();
        for (Object key : keySet) {
            map.put((String)key, properties.getProperty((String)key));
        }
        return map;
    }
    
    /**
     * 把属性文件转换成Map
     * 
     * @param inputStream
     * @return
     * @throws Exception
     */
    public static final Map<String, String> getPropertiesMap(InputStream inputStream) throws Exception{
        Properties properties = new Properties();
        properties.load(inputStream);
        Map<String, String> map = new HashMap<String, String>();
        Set<Object> keySet = properties.keySet();
        for (Object key : keySet) {
            map.put((String)key, properties.getProperty((String)key));
        }
        return map;
    }
    
    /**
     * 把文本文件转换成String
     * 
     * @param fullPath
     * @return
     * @throws Exception
     */
    public static String readFile(String fullPath) throws Exception{
        BufferedReader reader = new BufferedReader(new FileReader(fullPath));
        StringBuilder builder = new StringBuilder("");
        String line = null;
        while((line = reader.readLine()) != null) {
            builder.append(line + "\n");
        }
        reader.close();
        return builder.toString();
    }
    
    /**
     * 获取资源文件流
     * 
     * @param clazz
     * @param name
     * @return
     */
    public static InputStream getResourceAsStream(Class<?> clazz,String name) {
        try {
            InputStream inputStream = clazz.getResourceAsStream(name);
            if(inputStream == null) {
                inputStream = clazz.getClassLoader().getResourceAsStream(name);
            }
            return inputStream;
        } catch (Exception e) {
            	HLogger.DEFAULT().warn("获取资源文件失败:", e);
            return null;
        }
    }
    
    public static byte[] readAllBytes(String fileName){
    	try {
    		if(exists(fileName)){
				try(InputStream in = new FileInputStream(fileName)){
					int byteCount = in.available();
					byte[] bytes = new byte[byteCount];
					in.read(bytes, 0, byteCount);					
					return bytes;
				}
    		}
		} catch (FileNotFoundException e) {
			e.printStackTrace();			
		} catch (IOException e) {
			e.printStackTrace();
		}
    	return null;
    }
    
    public static boolean exists(String fileName){
    	File file = new File(fileName);
    	return file.exists();
    }
    
    public static String pathCombine(String path1,String path2){
    	if(path1.endsWith("/")) {
    		path1 = path1.substring(0,path1.length()-1);
    	}
    	if(path2.startsWith("/")) {
    		path2 = path2.substring(1);
    	}
    	String path = path1 + "/" + path2;
    	return path;
    }
}
